package vip.wangwenhao.autoconfigure.aspect;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import vip.wangwenhao.autoconfigure.service.CacheKeyGenerator;
import vip.wangwenhao.common.enums.ResultCode;
import vip.wangwenhao.common.exception.CommonException;

import java.util.concurrent.TimeUnit;

/**
 * 本地防重增强类 - 基于本地缓存
 *
 * @author wangwenhao
 */
@Aspect
@Configuration
public class LocalResubmitLockAspect {

    private static final Cache<String, Object> CACHES = CacheBuilder.newBuilder()
            // 最大缓存 100 个
            //.maximumSize(100)
            // 设置写缓存后 5 秒钟过期
            .expireAfterWrite(5, TimeUnit.SECONDS)
            .build();
    private final CacheKeyGenerator cacheKeyGenerator;


    @Autowired
    public LocalResubmitLockAspect(CacheKeyGenerator cacheKeyGenerator) {
        this.cacheKeyGenerator = cacheKeyGenerator;
    }

    @Around("execution(public * *(..)) && @within(vip.wangwenhao.common.annotations.LocalResubmitLock)")
    public Object interceptor(ProceedingJoinPoint pjp) throws Throwable {
        String key = cacheKeyGenerator.getLockKey(pjp);
        if (!StringUtils.isEmpty(key)) {
            if (CACHES.getIfPresent(key) != null) {
                throw new CommonException(ResultCode.RESUBMIT);
            }
            // 如果是第一次请求,就将 key 当前对象压入缓存中
            CACHES.put(key, key);
        }
        try {
            return pjp.proceed();
        } finally {
            //为了演示效果,这里就不调用了
            CACHES.invalidate(key);
        }
    }

}